
/* Thanks go out to Steven Haines for providing on the web the base of
 * this tail program.
 *
 * Minor Modifications were made for additional functionality.
 *
 * Original source can be found at:
 *
 * http://www.informit.com/guides/content.aspx?g=java&seqNum=226
 */

package com.dmdba.util.tail;

import java.io.*;
import java.util.*;

public class LogFileTailer extends Thread{
  private long sampleInterval = 5000;
  private File logfile;
  private String[] args;
  private boolean startAtBeginning = false;
  private boolean tailing = false;
  private Set listeners = new HashSet();

  public LogFileTailer( File file )
  {
    this.logfile = file;
  }

  public LogFileTailer( File file, long sampleInterval, boolean startAtBeginning )
  {
    this.logfile = file;
    this.sampleInterval = sampleInterval;
  }

    public LogFileTailer( String[] args, long sampleInterval, boolean startAtBeginning )
  {
    this.args = args;
    this.logfile =  new File( args[0] );
    this.sampleInterval = sampleInterval;
  }

  public void addLogFileTailerListener( LogFileTailerListener l )
  {
    this.listeners.add( l );
  }

  public void removeLogFileTailerListener( LogFileTailerListener l )
  {
    this.listeners.remove( l );
  }

  protected void fireNewLogFileLine( String line )
  {
    for( Iterator i=this.listeners.iterator(); i.hasNext(); )
    {
      LogFileTailerListener l = ( LogFileTailerListener )i.next();
      l.newLogFileLine( line );
    }
  }

  public void stopTailing()
  {
    this.tailing = false;
  }

    @SuppressWarnings ({"SleepWhileHoldingLock", "CallToThreadDumpStack"})
  public void run()
  {
    long filePointer = 0;
    if( this.startAtBeginning )
    {
      filePointer = 0;
    }
    else
    {
      filePointer = this.logfile.length();
    }

    try
    {
      this.tailing = true;
      RandomAccessFile file = new RandomAccessFile( logfile, "r" );
      while( this.tailing )
      {
        try
        {
          long fileLength = this.logfile.length();
          if( fileLength < filePointer )
          {
            file = new RandomAccessFile( logfile, "r" );
            filePointer = 0;
          }

          if( fileLength > filePointer )
          {
            file.seek( filePointer );
            String line = file.readLine();
            while( line != null )
            {
              this.fireNewLogFileLine( line );
              line = file.readLine();
            }
            filePointer = file.getFilePointer();
          }

          sleep( this.sampleInterval );
        }
        catch( Exception e )
        {
        }
      }
      file.close();
    }
    catch( Exception e )
    {
      e.printStackTrace();
    }
  }
}